最短路
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Problem Description
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?
Input
输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
输入保证至少存在1条商店到赛场的路线。
Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
Sample Input
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0
Sample Output
3
2
题目链接:最短路
代码:
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Problem Description
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?
Input
输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
输入保证至少存在1条商店到赛场的路线。
Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
Sample Input
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0
Sample Output
3
2
题目链接:最短路
代码:
//Dijkstra
#include
#include
#include
#include
using namespace std;
const int MAX = 1 << 30;
int n,m,vis[110],dist[110];
struct node //存储边的终点,以及权值
{
int v,w;
node(int vv,int ww) : v(vv),w(ww) {}
node() {}
};
vector
G[110]; void make_G() { int st,ed,c; for(int i = 1;i <= n;i++) { //初始化 G[i].clear(); vis[i] = 0; dist[i] = MAX; } for(int i = 0;i < m;i++) { scanf("%d%d%d",&st,&ed,&c); G[st].push_back(node (ed,c)); G[ed].push_back(node (st,c)); } } void dijkstra() { dist[1] = 0; for(int i = 0;i < n;i++) { //从未选点集中选点,并加入已选点集 int p,mn = MAX; for(int j = 1;j <= n;j++) { //未选点 中 距离 已选点 最近的点 if(!vis[j] && dist[j] <= mn) { p = j,mn = dist[j]; } } vis[p] = 1; //标记选择 for(int j = 0;j < G[p].size();j++) { //更新选择后的dist数组,也就是源点到其他点的最短距离 if(dist[G[p][j].v ] > dist[p] + G[p][j].w){ dist[G[p][j].v ] = dist[p] + G[p][j].w; } } } printf("%d\n",dist[n]); } int main() { while(~scanf("%d%d",&n,&m) && n && m) { make_G(); dijkstra(); } return 0; }#include
#include
#include
#include
using namespace std; int n,m,vis[110]; struct node { int v,w; node(int vv,int ww) : v(vv),w(ww) {} node() {} bool operator < (const node &a) const //运算符重载,保证权值小的边优先级高 { return w > a.w; } }; vector
G[110]; void make_G() { int st,ed,c; for(int i = 1;i <= n;i++) { G[i].clear(); vis[i] = 0; } for(int i = 0;i < m;i++) { scanf("%d%d%d",&st,&ed,&c); G[st].push_back(node (ed,c)); G[ed].push_back(node (st,c)); } } void dijkstra() { priority_queue
qe; qe.push(node (1,0)); node p; while(!qe.empty()) { p = qe.top(); qe.pop(); if(vis[p.v]) continue; //之前处理过(队列先处理最优的) vis[p.v] = 1; if(p.v == n) break; for(int i = 0;i < G[p.v].size();i++) { node q = G[p.v][i]; if(!vis[q.v]) { //从已选点开始可更新的边都入队,当然也可以改成判断队列是否已经有这条边 q.w = p.w + q.w; qe.push(node (q.v,q.w)); } } } printf("%d\n",p.w); } int main() { while(~scanf("%d%d",&n,&m) && n && m) { make_G(); dijkstra(); } return 0; }//bellman-ford #include
#include
#include
#include
using namespace std; const int MAX = 1<<30; int n,m,vis[110],dist[110]; struct node { int u,v,w; node(int uu,int vv,int ww) : u(uu),v(vv),w(ww) {} node() {} }; vector
G; void make_G() { int st,ed,c; G.clear(); for(int i = 1;i <= n;i++) { vis[i] = 0; dist[i] = MAX; } for(int i = 0;i < m;i++) { scanf("%d%d%d",&st,&ed,&c); G.push_back(node (st,ed,c)); G.push_back(node (ed,st,c)); } } void bellman_ford() { dist[1] = 0; for(int j = 1;j < n;j++) {
//n-1次松弛 for(int i = 0;i < G.size();i++) {
//对每条边进行处理 int u,v; u = G[i].u,v = G[i].v; if(dist[v] > dist[u] + G[i].w) { dist[v] = dist[u] + G[i].w; } } for(int i = 0;i < G.size();i++) {
//此题可以省略 int u,v; u = G[i].u,v = G[i].v; if(dist[v] > dist[u] + G[i].w) { printf("有环!\n"); } } } } int main() { while(~scanf("%d%d",&n,&m) && n && m) { make_G(); bellman_ford(); printf("%d\n",dist[n]); } return 0; }#include
#include
#include
#include
using namespace std; const int MAX = 1e7; int n,m,dist[110]; struct node { int v,w; node(int vv,int ww) : v(vv),w(ww) {} node() {} bool operator < (const node &a) const { return w > a.w; } }; vector
G[110]; void make_G() { int st,ed,c; for(int i = 1;i <= n;i++) { dist[i] = MAX; G[i].clear(); } for(int i = 0;i < m;i++) { scanf("%d%d%d",&st,&ed,&c); G[st].push_back(node (ed,c)); G[ed].push_back(node (st,c)); } } void spfa() { priority_queue
qe; int updataTimes[110]; memset(updataTimes,0,sizeof(updataTimes)); node p = node (1,0); qe.push(p); dist[p.v] = 0; while(!qe.empty()) { p = qe.top(); qe.pop(); for(int i = 0;i < G[p.v].size();i++) { node q = G[p.v][i]; if(dist[q.v] > dist[p.v] + q.w) { dist[q.v] = dist[p.v] + q.w; qe.push(node (q.v,dist[q.v])); if(++ updataTimes[q.v] >= n) { //更新次数超过n次,有环 printf("有环\n"); } } } } printf("%d\n",dist[n]); } int main() { while(~scanf("%d%d",&n,&m) && n && m) { make_G(); spfa(); } return 0; }#include
#include
#include
#include
using namespace std; const int MAX = 1 << 30; int n,m,path[110][110]; void make_G() { int st,ed,c; for(int i = 1;i <= n;i++) { for(int j = 1;j <= n;j++) { path[i][j] = MAX; } } for(int i = 0;i < m;i++) { scanf("%d%d%d",&st,&ed,&c); path[st][ed] = path[ed][st] = c; } } void floyd() { for(int k = 1;k <= n;k++) {
//注意枚举点的循环的位置 for(int i = 1;i <= n;i ++) { for(int j = 1;j <= n;j++) { if(path[i][k] == MAX || path[k][j] == MAX) continue; if(path[i][j] > path[i][k] + path[k][j]) { path[i][j] = path[i][k] + path[k][j]; } } } } } int main() { while(~scanf("%d%d",&n,&m) && n && m) { make_G(); floyd(); printf("%d\n",path[1][n]); } return 0; }